<HTML><HEAD><TITLE>library(notify_ports)</TITLE></HEAD><BODY>
[ <A HREF="../../index.html">Reference Manual</A> | <A HREF="../../fullindex.html">Alphabetic Index</A> ]<H1>library(notify_ports)</H1>
One-to-many and many-to-many notification ports
<H2>Predicates</H2>
<BLOCKQUOTE>
<DL>
<DT><A HREF="close_sender-1.html"><STRONG>close_sender(+SendPort)</STRONG></A></DT>
<DD>Close a send port</DD>
<DT><A HREF="close_sender-2.html"><STRONG>close_sender(+Pos, +Struct)</STRONG></A></DT>
<DD>Close a send port on a structure field</DD>
<DT><A HREF="foreachnotification-6.html"><STRONG>foreachnotification(+BaseName, -Message, +Params, +ReceivePort, -Status, +Goals)</STRONG></A></DT>
<DD>A control construct to iterate over received notifications</DD>
<DT><A HREF="foreachnotification-7.html"><STRONG>foreachnotification(+BaseName, -Message, +Params, +ReceivePos, +ReceiveStruct, -Status, +Goals)</STRONG></A></DT>
<DD>A control construct to iterate over received notifications</DD>
<DT><A HREF="open_receiver-2.html"><STRONG>open_receiver(+SendPort, -ReceivePort)</STRONG></A></DT>
<DD>Create a receiver for a given notification sender</DD>
<DT><A HREF="open_receiver-4.html"><STRONG>open_receiver(+SendPos, +SendStruct, +ReceivePos, +ReceiveStruct)</STRONG></A></DT>
<DD>Create a receiver for a given notification sender</DD>
<DT><A HREF="open_receiver_init-4.html"><STRONG>open_receiver_init(+SendPort, +InitialMessages, -InitialMessagesTail, -ReceivePort)</STRONG></A></DT>
<DD>Create a receiver for a given notification sender</DD>
<DT><A HREF="open_receiver_init-6.html"><STRONG>open_receiver_init(+SendPos, +SendStruct, +InitialMessages, -InitialMessagesTail, +ReceivePos, +ReceiveStruct)</STRONG></A></DT>
<DD>Create a receiver for a given notification sender</DD>
<DT><A HREF="open_sender-1.html"><STRONG>open_sender(-SendPort)</STRONG></A></DT>
<DD>Create a send port</DD>
<DT><A HREF="open_sender-2.html"><STRONG>open_sender(+Pos, +Struct)</STRONG></A></DT>
<DD>Initialise a structure field as a send port</DD>
<DT><A HREF="open_tagged_receiver-3.html"><STRONG>open_tagged_receiver(+Tag, +SendPort, ?ReceivePort)</STRONG></A></DT>
<DD>Create a receiver for one or more tagging senders</DD>
<DT><A HREF="open_tagging_sender-1.html"><STRONG>open_tagging_sender(-SendPort)</STRONG></A></DT>
<DD>Create a many-to-many send port </DD>
<DT><A HREF="receive_notifications-3.html"><STRONG>receive_notifications(+ReceivePort, -Messages, -Status)</STRONG></A></DT>
<DD>Receive a list of currently available notification messages</DD>
<DT><A HREF="receive_notifications-4.html"><STRONG>receive_notifications(+ReceivePos, +ReceiveStruct, -Messages, -Status)</STRONG></A></DT>
<DD>Receive a list of currently available notification messages</DD>
<DT><A HREF="send_notification-2.html"><STRONG>send_notification(+SendPort, +Message)</STRONG></A></DT>
<DD>Send a notification message</DD>
<DT><A HREF="send_notification-3.html"><STRONG>send_notification(+Pos, +Struct, +Message)</STRONG></A></DT>
<DD>Send a notification message</DD>
</DL>
</BLOCKQUOTE>
<H2>Description</H2>
<P>
    This library implements a nonlogical feature, called notification
    ports.  They are a form of messaging, i.e. there is are send ports
    and attached receive ports, and messages in the form of general terms
    can be passed through these ports.  Both send and receive ports have
    unique handles, which is the nonlogical bit.
    </P><P>
    There are two variants of this feature, one-to-many and many-to-many
    ports.
    </P>

    <h3>One-To-Many</h3>
    <P>
    In the one-to-many variant, messages sent from a single send port
    can be received independently by several receivers. In this setting,
    the message stream is essentially an infinite list, with the sender
    extending the list at the tail and the receivers each individually
    progressing through the list.
    </P><P>
    Straightforward interface:
    <PRE>
	open_sender(-Sender)
	close_sender(+Sender)
	send_notification(+Sender, +Message)
	open_receiver(+Sender, -Receiver)
	open_receiver_init(+Sender, +InitMsgs, -InitMsgsTail, -Receiver)
	receive_notifications(+Receiver, -Messages, -Status)
	foreachnotification(+BaseName, -Message, +Params, +Receiver, -Status, +Goals)
    </PRE>
    There is also a slightly more memory efficient API where sender and
    receiver can be fields of larger structures rather than separate
    substructures. These  larger structures must always be created
    by the caller (in the case of the sender this is often an attribute
    structure, in the case of the receiver it is sometimes advantageous
    to package a suspension together with the receiver in order to kill
    it at the end of all messages):
    <PRE>
	open_sender(+SendPos, +SendStruct)
	close_sender(+SendPos, +SendStruct)
	send_notification(+SendPos, +SendStruct, +Message)
	open_receiver(+SendPos, +SendStruct, +ReceivePos, +ReceiveStruct)
	open_receiver_init(+SendPos, +SendStruct, +InitMsgs, -InitMsgsTail,
				+ReceivePos, +ReceiveStruct)
	receive_notifications(+ReceivePos, +ReceiveStruct, -Messages, -Status)
	foreachnotification(+BaseName, -Message, +Params, +ReceivePos, +ReceiveStruct, -Status, +Goals)
    </PRE>

    <h3>Many-To-Many</h3>
    <P>
    In the many-to-many variant, several send ports can be connected
    to several receive ports in an arbitray manner.
    To enable a receiver to distinguish messages from multiple senders,
    the messages get tagged with a sender- and receiver-specific id as
    they are received.
    </P>
    The corresponding predicates are the following. Note that sender and
    receiver are opened with different predicates, but the send and receive
    predicates are the same as for one-to-many ports:
    <PRE>
	open_tagging_sender(-Sender)
	open_tagged_receiver(+Tag, +Sender, -Receiver)

	send_notification(+Sender, +Message)
	receive_notifications(+Receiver, -Messages, -Status)
	foreachnotification(+BaseName, -Message, +Params, +Receiver, -Status, +Goals)
    </PRE>
    Note that closing of tagging senders is currently not implemented.
    
<H2>Examples</H2>
<PRE>
    % One-to-many

    % This example shows a typical use of notification ports.
    % A notification port is used in addition to a waking list
    % in order to transfer precise information about the reason for waking.

    % We define a variable attribute (myattr) consisting of a send port
    % and a waking list. 


    :- lib(notify_ports).

    :- meta_attribute(myattr, []).
    :- local struct(myattr(port,susplist)).
    :- local struct(myrec(port,susp)).


    test :-
	    init_var(X),
	    log_all_messages(X),
	    touch_var(X, hello),
	    touch_var(X, out),
	    touch_var(X, there),
	    fini_var(X).


    % initialise and attach our attribute to the given variable
    init_var(X) :-
	    Attr = myattr{},
	    open_sender(port of myattr, Attr),
	    init_suspension_list(susplist of myattr, Attr),
	    add_attribute(X, Attr, myattr).


    % simulate an action on the variable: send a message and wake
    touch_var(_X{myattr:Attr}, Message) ?-
	    send_notification(port of myattr, Attr, Message),
	    schedule_suspensions(susplist of myattr, Attr),
	    wake.

    % finalise the attribute, e.g. before the variable gets instantiated
    fini_var(_X{myattr:Attr}) ?-
            close_sender(port of myattr, Attr),
	    schedule_suspensions(susplist of myattr, Attr),
	    wake.

    % a sample demon that will report every time the variable is touched
    log_all_messages(X{myattr:Attr}) ?-
	    Receiver = myrec{susp:Susp},
	    open_receiver(port of myattr, Attr, port of myrec, Receiver),
	    suspend(log_demon(Receiver), 2, X-&gt;myattr:(susplist of myattr), Susp).

    :- demon log_demon/1.
    log_demon(Receiver) :-
	    foreachnotification(log, Message, [], port of myrec, Receiver, Status, (
		writeln(received(Message))
	    )),
	    ( Status = closed -&gt;
		arg(susp of myrec, Receiver, Susp),
		kill_suspension(Susp),
		writeln(closed)
	    ;
		true
	    ).
    

    ( For a many-to-many example, see open_tagged_receiver/3 )
    </PRE>
<H2>About</H2><UL COMPACT>
<LI><STRONG>Author: </STRONG>Joachim Schimpf
<LI><STRONG>Copyright &copy; </STRONG>Cisco Systems, Inc
<LI><STRONG>Date: </STRONG>$Date: 2009/02/19 05:38:37 $
</UL>
<HR>Generated from notify_ports.eci on 2009-05-27 01:25
</BODY></HTML>
